<template>
	<el-row style="width: 100%">
		<template v-for="(item, i) in rowForCfg.isfor ? props.pageData[props.rowForCfg.forBind] : 1" :key="'forRow' + i">
			<template v-for="(cpn, index) in cpns" :key="index">
				<template v-if="cpn.tag === 'el-row' && cpn.showEle">
					<el-col :span="cpn.attrs.span">
						<el-row :style="getRowStyle(cpn)" :class="[cpn.attrs.boxShadow, { rowHover: cpn.attrs.hover }]" class="bbbsss">
							<CustomizePageForm
								v-if="cpn.children && cpn.children.length && cpn.attrs.layoutStruc.position === '0'"
								:page-info="pageInfo"
								:is-form="isForm"
								:cpns="cpn.children"
								:pageData="props.pageData"
								:input-data="props.inputData"
								:global-data="props.globalData"
								:datar="datar"
								:style-class="styleClass"
								:rowForCfg="{ isfor: cpn.attrs.isForEle, forBind: cpn.attrs.pageArray, item: item !== 1 ? item : null }"
								@handleEmitEvent="handleEmitEvent"
								@setFormData="setFormData"
								@clone="clone"
								@updateFormData="updateFormData"
								:formRef="formRef"
								:style="getRowStyle(cpn)"
							/>
							<CustomTablePape
								v-else-if="cpn.attrs.layoutStruc.position === '1'"
								:inputData="{ ...props.inputData, ...getCarryParams(cpn.attrs.layoutStruc.params) }"
								:pageid="cpn.attrs.layoutStruc.pageid"
							/>
							<CustomPage v-else-if="cpn.attrs.layoutStruc.position === '2'" :pageid="cpn.attrs.layoutStruc.pageid" :inputData="inputData" />
						</el-row>
					</el-col>
				</template>
				<template v-else>
					<el-col v-if="cpn.showEle" :span="cpn.attrs.span">
						<!-- label-width:标签标题的宽度 -->
						<el-form-item
							:label="cpn.attrs.label"
							:label-width="cpn.attrs.labelWidth"
							:rules="genRules(cpn.attrs)"
							:prop="cpn.vModel"
							class="form-item"
						>
							<component
								:ref="(el: any) => setRefInfo(el, cpn.tag + cpn.formId)"
								:is="getComponent(eleName(cpn.execTag))"
								:inputData="inputData"
								:pageData="pageData"
								:globalData="globalData"
								:FieldItem="getFieldItem(cpn)"
								:filterIdx="index"
								:modelValue="getModelVal(cpn, item)"
								@update:modelValue="($e:any) => getModelVal(cpn, item,$e)"
								@handleClick="($e:any) => handleClick($e,cpn.tag + cpn.formId)"
								@handleEmitEvent="handleEmitEvent"
								located="Add"
							/>
						</el-form-item>
					</el-col>
				</template>
			</template>
		</template>
	</el-row>
</template>
<script lang="ts">
import { getComponent } from '/@/utils/componentFactory';
import { calcFieldValue } from '/@/components/Linxyun/custom/CustomCommon/lxy_expression.js';
import { ElMessage } from 'element-plus';

export default defineComponent({
	name: 'CustomizePageForm',
	components: {
		CustomTablePape: defineAsyncComponent(() => import('/@/components/Linxyun/custom/CustomTablePape/index.vue')),
		CustomPage: defineAsyncComponent(() => import('/@/components/Linxyun/custom/CustomizePageForm/showCustomPage.vue')),
	},
	props: reactive<Record<string, any>>({
		pageid: { type: Number, default: 0 },
		pageInfo: { type: Object, default: null },
		isForm: { type: Boolean, default: false },
		datar: { type: Object, default: null },
		cpns: { type: Object, default: () => reactive([]) },
		styleClass: { type: Object, default: null },
		pageData: { type: Object, default: null },
		inputData: { type: Object, default: null },
		globalData: { type: Object, default: null },
		rowForCfg: { type: Object, default: () => reactive({ isfor: false }) },
		formRef: { type: Object, default: () => ({}) },
	}),
	emits: ['queryData', 'clone', 'handleEmitEvent', 'setFormData', 'clone', 'updateFormData'],
	setup(props, ctx) {
		let { proxy } = <any>getCurrentInstance();
		const refInfo = ref<Record<string, any>>({});
		let cascadeEle = ref<any[]>([]);
		onMounted(() => {
			props.cpns.forEach((ele: any) => {
				if (!ele.attrs.relationConfig.open || ele.attrs.relationConfig.mode === 'update') {
					ele.showEle = true;
				}
			});
			cascadeEle.value = props.cpns.filter((f: any) => f.attrs.relationConfig.open);
			proxy.$forceUpdate();
		});

		// 对开启级联的组件进行相应的操作
		const cascadeControl = () => {
			for (let i = 0; i < cascadeEle.value.length; i++) {
				const ele = cascadeEle.value[i];
				if (['showAndUpdate', 'show'].includes(ele.attrs.relationConfig.mode)) {
					ele.showEle = calcFieldValue(4, ele.attrs.relationConfig.show.params.value, props.inputData, props.pageData, props.globalData);
				}
				if (['update', 'showAndUpdate'].includes(ele.attrs.relationConfig.mode)) {
					const propTmp = props as Record<string, any>;
					if (ele.attrs.relationConfig.update.funOrExp === 'exp') {
						propTmp[ele.attrs.bindObj][ele.vModel] = calcFieldValue(
							4,
							ele.attrs.relationConfig.update.expres,
							props.inputData,
							props.pageData,
							props.globalData
						);
					} else {
						for (let parent = 0; parent < ele.attrs.relationConfig.ParentID.length; parent++) {
							const ParentObj = props.cpns.find((f: any) => f.formId === ele.attrs.relationConfig.ParentID[parent]);
							watch(
								() => propTmp[ParentObj.attrs.bindObj][ParentObj.vModel],
								() => {
									if (!ele.IsRequest) {
										if (ele.attrs.relationConfig.update.funMode === 'page') {
											handleClick(ele.attrs.relationConfig.update.dynamicOptions);
											ele.IsRequest = true;
										} else {
											refInfo.value[ele.tag + ele.formId].init();
											ele.IsRequest = true;
										}
									} else {
										setTimeout(() => {
											ele.IsRequest = false;
										}, 500);
									}
								}
							);
						}
					}
				}
				// console.log('resultresult', ele, ele.showEle);
			}
		};
		watch(
			() => [props.inputData, props.pageData, props.globalData],
			() => {
				cascadeControl();
			},
			{ deep: true }
		);

		const eleNameEume = reactive<{ [x: string]: string }>({
			tinymce: 'rich',
		});
		const eleName = computed(() => {
			return (ele: string) => {
				console.log('eleName', ele);
				if (['tinymce'].includes(ele)) {
					return eleNameEume[ele];
				} else {
					return 'el-' + ele;
				}
			};
		});

		const getFieldItem = computed(() => {
			return (cpn: { [x: string]: any }) => {
				if (!cpn.attrs.bindObj) {
					cpn.attrs.bindObj = 'pageData';
				}
				const size = {
					medium: 'large',
					small: 'default',
					mini: 'small',
				};
				cpn.attrs.size = size[cpn.attrs.size];
				const param = {
					PageID: props.pageid,
					FieldID: cpn.formId,
					FieldName: cpn.tag,
					Label: cpn.attrs.label,
					InputType: 'el-' + cpn.execTag,
					pageType: 'page',
					InputDataType: -1,
					...cpn,
				};
				if ((cpn.vModel && /\$.*\}/g.test(cpn.vModel)) || /'.*'$/g.test(cpn.vModel)) {
					param.InputDataType = 4;
				} else {
					param.InputDataType = 2;
				}
				return param;
			};
		});

		// 动态双向绑定
		const getModelVal = computed(() => {
			// item 如果当前组件是循环出来的，则保存的是循环数组中的对象，否则为空；e为组件的输入值
			return (cpn: any, item: any, e?: any) => {
				// 组件没有绑定变量这个参数就会在pageData中有一个undefined属性，类似一个tabs组件
				if (!cpn.attrs.bindObj) return '';
				if (cpn.attrs.bindObj === 'pageDataTemp') {
					cpn.attrs.bindObj = 'pageData';
				}
				const propsTemp = props;
				console.log('getModelVal:', { item, cpn, propsTemp, e });
				/**
				 * @rowForCfg中的属性说明
				 * @isfor 当前是否为循环组件
				 * @forBind 是否有循环绑定变量
				 * @item 保存循环容器绑定的数组 （上级为循环组件时，这个属性才会有值）
				 */
				// 自身和上级都非循环容器
				if (!props.rowForCfg.isfor && !props.rowForCfg.forBind && !props.rowForCfg.item) {
					if (e !== undefined) {
						// 赋值给当前组件绑定的变量
						//bindObj是这三种之一（pageData，inputData，globalData）
						propsTemp[cpn.attrs.bindObj][cpn.vModel] = e;
					} else if ([undefined, NaN].includes(props[cpn.attrs.bindObj][cpn.vModel])) {
						propsTemp[cpn.attrs.bindObj][cpn.vModel] =
							cpn?.defaultValue && ![undefined, null, NaN].includes(cpn?.defaultValue) ? cpn?.defaultValue : '';
					}
					return props[cpn.attrs.bindObj][cpn.vModel];
				} else if (!props.rowForCfg.item) {
					// 上级不是循环容器，但自身是循环容器
					if (e !== undefined) {
						item[cpn.vModel] = e;
					} else if (item[cpn.vModel] === undefined) {
						item[cpn.vModel] = cpn?.defaultValue && ![undefined, null, NaN].includes(cpn?.defaultValue) ? cpn?.defaultValue : '';
					}
					return item[cpn.vModel];
				} else {
					// 上级为循环容器，自身不为循环容器
					if (e !== undefined) {
						propsTemp.rowForCfg.item[cpn.vModel] = e;
					} else if (props.rowForCfg.item[cpn.vModel] === undefined) {
						propsTemp.rowForCfg.item[cpn.vModel] = cpn?.defaultValue && ![undefined, null, NaN].includes(cpn?.defaultValue) ? cpn?.defaultValue : '';
					}
					return props.rowForCfg.item[cpn.vModel];
				}
			};
		});

		// 行容器样式
		const getRowStyle = computed(() => {
			return (cpn: any) => {
				return {
					height: cpn.attrs.height > 0 ? cpn.attrs.height + 'px' : 'auto',
					marginTop: cpn.attrs.marginTop + 'px',
					marginRight: cpn.attrs.marginRight + 'px',
					marginBottom: cpn.attrs.marginBottom + 'px',
					marginLeft: cpn.attrs.marginLeft + 'px',
					paddingTop: cpn.attrs.paddingTop + 'px',
					paddingRight: cpn.attrs.paddingRight + 'px',
					paddingBottom: cpn.attrs.paddingBottom + 'px',
					paddingLeft: cpn.attrs.paddingLeft + 'px',
					borderRadius: cpn.attrs.borderRadius + 'px',
					background: cpn.attrs.backgroundImg ? `url('${cpn.attrs.backgroundImg}') 0% 0% / 100% 100% no-repeat` : 'none',
					backgroundColor: cpn.attrs.backgroundColor,
					overflow: cpn.attrs.overflow,
					justifyContent: cpn.attrs.justify,
				};
			};
		});
		// 触发事件
		const handleClick = async (bntDefine: { [x: string]: any }, elName?: string) => {
			console.log('refInfo.valuerefInfo.value', elName, refInfo.value);
			console.log('handleClick', props.formRef);
			props.formRef.validate(async (valid: boolean) => {
				if (valid) {
					const formData = {
						...toRefs(props.pageData),
						...toRefs(props.inputData),
						...toRefs(props.globalData),
					};
					console.log('formDataformDataformData', formData);
					await checkData(bntDefine, formData);
					console.log('[Debug][BntEvent]: ', bntDefine, formData);
					handleEmitEvent('handleClick', bntDefine);
				} else {
					ElMessage.warning('请填写必传字段');
				}
			});
		};

		const checkData = async (bntDefine: { [x: string]: any }, formData: any) => {
			if (props.pageInfo && bntDefine.actions && bntDefine.actions.list) {
				for (let i = 0; i < bntDefine.actions.list.length; i++) {
					const eventObj = props.pageInfo.getEvent(bntDefine.actions.list[i]);
					if (eventObj === null) {
						console.error('[Error][CustomPage][BntEvent]The event is not exist: ', bntDefine.actions.list[i]);
						continue;
					}
					if (!eventObj._input_params_define) {
						continue;
					}
					const eventJson = JSON.stringify(eventObj._input_params_define);

					for (let j = 0; j < props.cpns.length; j++) {
						const cpn = props.cpns[j];
						if (cpn.tag === 'el-upload' && cpn.vModel) {
							const varStr = '${' + cpn.vModel + '}';
							if (eventJson.indexOf(varStr) >= 0) {
								// 输入变量包含了该上传组件,则需要将文件上传
								const fileList = await refInfo.value[cpn.tag + cpn.formId].uploadSubmit();
								console.log('[DeBug][FileList]:', fileList);
								// eslint-disable-next-line vue/no-mutating-props
								props[cpn.attrs.bindObj][cpn.vModel] = ref(fileList2Data(fileList));
							}
						} else if (cpn.tag === 'tinymce' && cpn.vModel) {
							const varStr = '${' + cpn.vModel + '}';
							if (eventJson.indexOf(varStr) >= 0) {
								// 保存文件
								if (cpn.attrs.isSaveFile) {
									const res = await refInfo.value[cpn.tag + cpn.formId].uploadSubmit();
									if (res) {
										formData[cpn.vModel].value = res;
									}
								}
							}
						}
					}
				}
			}
		};
		const fileList2Data = (fileList: Record<string, any>) => {
			if (!fileList) {
				return '';
			}
			let data = '';
			for (let i = 0; i < fileList.length; i++) {
				if (i > 0) {
					data += ';';
				}
				data = data + fileList[i].name + ':=' + fileList[i].url;
			}
			return data;
		};

		const handleEmitEvent = (name: string, ...args: any) => {
			console.log('handleEmitEvent', name, args);
			ctx.emit('handleEmitEvent', name, ...args);
		};

		const setFormData = () => {
			console.log('setFormData');
		};

		const updateFormData = () => {
			console.log('updateFormData');
		};

		const clone = () => {
			console.log('clone');
		};

		//设置ref
		const setRefInfo = (el: any, itemKey: string) => {
			refInfo.value[itemKey] = el;
		};

		const genRules = (attrs: Record<string, any>) => {
			if (attrs.required) {
				console.log('genRules', attrs.required);
				return [{ required: true, message: '请输入' + attrs.name, trigger: 'blur' }];
			}
		};
		// 获取携带参数并解析
		const getCarryParams = (params: Array<Record<string, string>>) => {
			if (!params) {
				return {};
			}
			const newParams = {};
			for (let index = 0; index < params.length; index++) {
				const pItem = params[index];
				const value = calcFieldValue(4, pItem.value, props.inputData, props.pageData, props.globalData);
				[undefined, NaN, null, ''].includes(value) ? (newParams[pItem.name] = '') : (newParams[pItem.name] = value);

				console.log('getCarryParams', pItem.name, value);
			}

			return newParams;
		};
		return {
			props,
			getComponent,
			setRefInfo,
			getFieldItem,
			eleName,
			handleClick,
			handleEmitEvent,
			setFormData,
			updateFormData,
			clone,
			getRowStyle,
			cascadeControl,
			getModelVal,
			genRules,
			getCarryParams,
		};
	},
});
</script>
<style lang="scss" scoped>
// 行容器边框样式-----------------------------------
.ordinary {
	border: 1px solid #ccc;
}
.shadowA {
	box-shadow: inset 0 0 5px #ccc;
}
.shadowB {
	box-shadow: 2px 2px 10px #ccc;
}
.shadowC {
	box-shadow: 0 0 10px #ccc;
}
.shadowD {
	box-shadow: 0 0 10px 10px #ccc;
}
.threeDime {
	border-width: 10px;
	border-color: #ccc;
	border-style: ridge;
}
.rowHover:hover {
	transition: all 0.3s;
	box-shadow: 0 2px 12px #0000001a;
}

.form-item {
	align-items: center;
}
// ----------------------------------------------------
</style>
